package com.yonyou.sto.modules.ims.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.yonyou.sto.common.api.CommonResult;
import com.yonyou.sto.common.domain.OpenBillBuilder;
import com.yonyou.sto.domain.InvoiceStatusEnums;
import com.yonyou.sto.modules.ims.dto.CallbackInvoiceData;
import com.yonyou.sto.modules.ims.dto.CallbackInvoiceParam;
import com.yonyou.sto.modules.ims.dto.InvoiceDto;
import com.yonyou.sto.modules.ims.dto.OpenReturn;
import com.yonyou.sto.modules.ims.model.*;
import com.yonyou.sto.modules.ims.service.*;
import com.yonyou.sto.modules.ums.model.UmsAdmin;
import com.yonyou.sto.modules.ums.model.UmsNcCustomer;
import com.yonyou.sto.modules.ums.model.UmsNcCusttax;
import com.yonyou.sto.modules.ums.model.UmsNcOrg;
import com.yonyou.sto.modules.ums.service.UmsAdminService;
import com.yonyou.sto.modules.ums.service.UmsNcCustomerService;
import com.yonyou.sto.modules.ums.service.UmsNcOrgService;
import com.yonyou.sto.modules.ums.util.CacheUtilHttp;
import com.yonyou.sto.modules.ums.util.ExceptionUtil;
import com.yonyou.sto.modules.ums.util.HttpRestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.security.Principal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author ：Aegon Targaryen
 * @version ：1.0-SNAPSHOT
 * @date ：Created in 2020/9/25 14:12
 * @description ：
 * @modifiedBy ：
 */
@Service
@Transactional
public class OpenBillServiceImpl implements OpenBillService {

    private static final Logger LOGGER = LoggerFactory.getLogger(OpenBillServiceImpl.class);

    @Value("${yonyoucloud.app_id}")
    private String APP_ID;

    @Value("${yonyoucloud.nc_url}")
    private String NC_URL;

    @Value("${yonyoucloud.domain}")
    private String DOMAIN;

    @Value("${yonyoucloud.split_url}")
    private String SPLIT_URL;

    @Value("${yonyoucloud.red_url}")
    private String RED_URL;

    @Value("${yonyoucloud.special_red_url}")
    private String SPECIAL_RED_URL;

    @Value("${yonyoucloud.query_url}")
    private String QUERY_URL;

    @Value("${yonyoucloud.return_url}")
    private String RETURN_URL;
    @Value("${yonyoucloud.callback_url}")
    private String CALLBACK_URL;

    @Value("${yonyoucloud.callback_red_url}")
    private String CALLBACK_RED_URL;

    @Value("${yonyoucloud.callback_email}")
    private String CALLBACK_EMAIL;

    @Value("${yonyoucloud.callback_phone}")
    private String CALLBACK_PHONE;

    @Resource
    private ImsInvoiceService invoiceService;

    @Resource
    private ImsInvoiceItemService invoiceItemService;

    @Resource
    private ImsBillService billService;

    @Resource
    private PushBillService pushBillService;

    @Resource
    private ImsBuyerService buyerService;

    @Resource
    private UmsNcCustomerService umsNcCustomerService;
    @Resource
    private UmsNcOrgService orgService;
    @Resource
    private ImsPartyService partyService;

    @Resource
    private OpenBillBuilder openBillBuilder;

    @Resource
    private UmsAdminService adminService;

    @Resource
    private ImsReturnInvoiceService returnInvoiceService;

    @Resource
    private ImsReturnInvoiceItemService returnInvoiceItemService;



    /**
     * 开票申请
     * @param principal
     * @param billIds
     * @param billItemIds
     * @param billType
     * @param contain
     * @return
     */
    @Override
    public CommonResult callInvoiceApply(Principal principal, List<String> billIds, List<String> billItemIds, Integer billType, Integer contain) {

        if (billIds.size() > 10) return CommonResult.failed("每次最多申请10张单据");
        QueryWrapper<ImsInvoice> wrapper = new QueryWrapper<>();
        LambdaQueryWrapper<ImsInvoice> lambda = wrapper.lambda();
        lambda.in(ImsInvoice::getStatus, InvoiceStatusEnums.NOT.getCode(),InvoiceStatusEnums.HALF.getCode());
        lambda.in(ImsInvoice::getId,billIds);
        //lambda.in(ImsInvoice::getBillType,billType);
        List<ImsInvoice> invoices = invoiceService.list(wrapper);
        if (CollUtil.isEmpty(invoices)) {
            return CommonResult.failed("未查询到对应单据");
        }

        if (invoices.stream().filter(s->s.getStatus()==InvoiceStatusEnums.NOT.getCode()).collect(Collectors.toList()).size() == 0) {
            return CommonResult.failed("存在非未开票状态的单据,不能申请开票");
        }
        QueryWrapper<ImsInvoiceItem> billItemwrapper = new QueryWrapper<>();
        LambdaQueryWrapper<ImsInvoiceItem> billItemlambda = billItemwrapper.lambda();
        billItemlambda.in(ImsInvoiceItem::getManualId,billIds);
        //billItemlambda.isNotNull(ImsInvoiceItem::getTaxItemId);
        List<ImsInvoiceItem> items;
//        if (!CollUtil.isEmpty(billIds)) items = invoiceItemService.listByBillIds(billIds);
//        else items = invoiceItemService.list(billItemwrapper);
        items = invoiceItemService.list(billItemwrapper);
        if (items.size() == 0) {
            return CommonResult.failed("存在未选择税率的单据明细,不能开票");
        }
        if (items.stream().filter(s->s.getStatus()==InvoiceStatusEnums.NOT.getCode()).collect(Collectors.toList()).size() == 0) {
            return CommonResult.failed("存在非未开票状态的单据明细,不能开票");
        }

        UmsAdmin umsAdmin = adminService.getAdminByUsername(principal.getName());
        try {
            for (ImsInvoice es:invoices) {
                invoiceService.update(new LambdaUpdateWrapper<ImsInvoice>()
                        .eq(ImsInvoice::getId,es.getId())
                        .set(ImsInvoice::getStatus,InvoiceStatusEnums.APPLY.getCode())
                        .set(ImsInvoice::getApplyname,umsAdmin.getNickName())
                        .set(ImsInvoice::getApplycdoe,umsAdmin.getUsername())
                        .set(ImsInvoice::getBillType,billType)
                        .set(ImsInvoice::getApplydate, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
                        //.set(ImsInvoice::getApplyje,contain==1?es.getPayAmount().setScale(2, RoundingMode.HALF_UP).doubleValue():es.getWsje().setScale(2, RoundingMode.HALF_UP).doubleValue())
                        .set(ImsInvoice::getDef1,contain)
                );
                //invoiceService.updateStatusApply(es.getId(),umsAdmin.getNickName(),umsAdmin.getUsername(),billType,contain==1?es.getPayAmount().setScale(2, RoundingMode.HALF_UP).doubleValue():es.getWsje().setScale(2, RoundingMode.HALF_UP).doubleValue(),InvoiceStatusEnums.APPLY.getCode(),contain);
                //List<ImsInvoiceItem> items1 = items.stream().filter(em -> em.getBillId().equals(es.getId())).collect(Collectors.toList());
                List<ImsInvoiceItem> items1 = items.stream().filter(em -> em.getManualId().equals(es.getId())).collect(Collectors.toList());
                for (ImsInvoiceItem its:items1) {
                    LambdaUpdateWrapper<ImsInvoiceItem> lambdaUpdateWrapperb = new LambdaUpdateWrapper<>();
                    lambdaUpdateWrapperb.eq(ImsInvoiceItem::getId, its.getId())
                            .set(ImsInvoiceItem::getStatus, InvoiceStatusEnums.APPLY.getCode())
                            .set(ImsInvoiceItem::getApplyname,umsAdmin.getNickName())
                            .set(ImsInvoiceItem::getApplycdoe,umsAdmin.getUsername())
                            .set(ImsInvoiceItem::getApplydate, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                            //.set(ImsInvoiceItem::getApplyje,contain==1?its.getTaxAmount().setScale(2, RoundingMode.HALF_UP).doubleValue():its.getWsje().setScale(2, RoundingMode.HALF_UP).doubleValue());
                    invoiceItemService.update(lambdaUpdateWrapperb);
                    //invoiceItemService.updateStatusApply(its.getId(),umsAdmin.getNickName(),umsAdmin.getUsername(),billType,contain==1?its.getTaxAmount().setScale(2, RoundingMode.HALF_UP).doubleValue():its.getWsje().setScale(2, RoundingMode.HALF_UP).doubleValue(),InvoiceStatusEnums.APPLY.getCode(),contain);

                }
            }

        }catch (Exception e){
            LOGGER.info("开蓝票更新异常:   " + ExceptionUtil.getStackTrace(e));
            e.printStackTrace();
            return CommonResult.failed("开票失败,请检查单据信息");
        }


//        List<InvoiceDto> dtos = new ArrayList<>();
//        try {
//            GsonBuilder builder = new GsonBuilder();
//
//            invoices.forEach(es -> {
//                List<Object> datas = new ArrayList<>();
//                List<Object> urls = new ArrayList<>();
//                List<Object> emails = new ArrayList<>();
//                List<Object> phones = new ArrayList<>();
//
//                ImsBuyer buyer = buyerService.getBuyerByBuyerTaxSn(es.getBuyerTaxSn());
//                //ImsParty party = partyService.getPartyBySellerSn(es.getSellerSn());
//                UmsNcOrg org = orgService.getData(es.getSellerSn());
//                String serial = OpenBillBuilder.createSerialNumber();
//
//                Map<String, Object> data = new HashMap<>();
//                data.put("FPQQLSH", serial);
//                data.put("FPLX", billType);
//                data.put("BZ", es.getNote());
//                data.put("XSF_NSRSBH", org.getTaxpayerid());//纳税人识别号
//                data.put("XSF_MC", org.getName());//名字
//                data.put("XSF_DZDH", org.getCorpaddress() + org.getTel());//地址
////                data.put("XSF_YHZH", party.getSellerBankAccount());
//
//                data.put("GMF_NSRSBH", buyer.getBuyerTaxSn());
//                data.put("GMF_MC", buyer.getBuyerName());
//                data.put("GMF_DZDH", buyer.getBuyerAddress() + buyer.getBuyerPhone());
//                data.put("GMF_YHZH", buyer.getBuyerBankAccount());
//                data.put("ORGCODE", org.getCode());//组织编码
//                data.put("KPR", umsAdmin.getNickName());
//
//                List<ImsInvoiceItem> items1 = items.stream().filter(em -> em.getBillId().equals(es.getId())).collect(Collectors.toList());
//                BigDecimal reduce = BigDecimal.ZERO;
//                // 不含税传0,含税传1
//                if (contain == 0)
//                    reduce = items1.stream().map(ImsInvoiceItem::getProductAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
//                else if (contain == 1)
//                    reduce = items1.stream().map(ImsInvoiceItem::getTaxAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
//
//                data.put("JSHJ", reduce);
//                data.put("items", openBillBuilder.buildItems(items1, contain));
//                datas.add(data);
//
//                Map<String, Object> url = new HashMap<>();
//                url.put("fpqqlsh", serial);
//                url.put("url", CALLBACK_URL);
//                urls.add(url);
//
//                Map<String, Object> phone = new HashMap<>();
//                phone.put("fpqqlsh", serial);
//                phone.put("address", CALLBACK_PHONE);
//                phone.put("title", "电子发票 : " + serial);
//                phone.put("content", es.getBillContent());
//                phones.add(phone);
//
//                Map<String, Object> email = new HashMap<>();
//                email.put("fpqqlsh", serial);
//                email.put("address", CALLBACK_EMAIL);
//                phone.put("title", "电子发票 : " + serial);
//                phone.put("content", es.getBillContent());
//                emails.add(email);
//
//                Map<String, String> paramsMap = new HashMap<>();
//                paramsMap.put("requestdatas", builder.create().toJson(datas));
//                paramsMap.put("email", builder.create().toJson(emails));
//                paramsMap.put("sms", builder.create().toJson(phones));
//                paramsMap.put("url", builder.create().toJson(urls));
//                paramsMap.put("autoAudit", "true");
//
//                LOGGER.info("开蓝票接口参数报文:   " + paramsMap);
//
//                Map resultMap = openBillBuilder.callInvoiceApply(DOMAIN + SPLIT_URL + APP_ID, paramsMap);
//
//                LOGGER.info("开蓝票接口返回报文:   " + resultMap);
//                if ("0000".equals(resultMap.get("code"))) {
//                    billService.splitAddOpenBill(es.getBillSn(), (List<Map<String, Object>>) resultMap.get("datas"));
//
//                    InvoiceDto dto = new InvoiceDto();
//                    BeanUtils.copyProperties(es, dto);
//                    dto.setInvoiceItems(items1);
//                    dto.setTaxAmount(reduce);
//                    dto.setBillSerial(serial);
//                    dto.setBillType(billType);
//                    dto.setCreateTime(DateUtil.format(es.getCreateTime(), DatePattern.PURE_DATE_PATTERN));
//                    dtos.add(dto);
//                }
//            });
//        } catch (Exception e) {
//            e.printStackTrace();
//            return CommonResult.failed("开票失败,请检查单据信息");
//        }
//        // 修改单据状态
//        this.updateBatchInvoice(dtos);
//        // 推送开票信息到悦闻
//        pushBillService.pushBillClient(dtos);
        return CommonResult.success("申请成功");
    }

    /**
     * 开票退回申请
     *  退回成功后billtype改为-1
     * @param principal
     * @param billId
     * @return
     */
    @Override
    public CommonResult callInvoiceReturnApply(Principal principal, String billId) {

        if (StrUtil.isBlank(billId)) return CommonResult.failed("未选择单据");
        ImsInvoice invoice = invoiceService.getOne(new LambdaQueryWrapper<ImsInvoice>()
                .in(ImsInvoice::getStatus, InvoiceStatusEnums.NOT.getCode(), InvoiceStatusEnums.FAILED.getCode(), InvoiceStatusEnums.APPLY.getCode())
                .eq(ImsInvoice::getId, billId)
        );
        if (invoice==null){
            return CommonResult.failed("未查询到对应单据");
        }

//        if (invoice.getStatus()!=InvoiceStatusEnums.APPLY.getCode()){
//            return CommonResult.failed("存在非待开票的单据，不能退回开票");
//        }

        List<ImsInvoiceItem> invoiceItems = invoiceItemService.list(new LambdaQueryWrapper<ImsInvoiceItem>()
                .eq(ImsInvoiceItem::getManualId, billId)
        );
        UmsAdmin umsAdmin = adminService.getAdminByUsername(principal.getName());

        try {
            invoiceService.update(new LambdaUpdateWrapper<ImsInvoice>()
                    .eq(ImsInvoice::getId,invoice.getId())
                    .set(ImsInvoice::getStatus,InvoiceStatusEnums.NOT.getCode())
                    .set(ImsInvoice::getApplyname,umsAdmin.getNickName())
                    .set(ImsInvoice::getApplycdoe,umsAdmin.getUsername())
                    .set(ImsInvoice::getBillType,-1)
                    //.set(ImsInvoice::getApplyje,0)
            );
            //invoiceService.updateStatusApply(invoice.getId(),umsAdmin.getNickName(),umsAdmin.getUsername(),-1,0,InvoiceStatusEnums.NOT.getCode(),-1);
            for (ImsInvoiceItem invoiceItem:invoiceItems) {
                invoiceItemService.update(new LambdaUpdateWrapper<ImsInvoiceItem>()
                        .eq(ImsInvoiceItem::getId,invoiceItem.getId())
                        .set(ImsInvoiceItem::getStatus,InvoiceStatusEnums.NOT.getCode())
                        .set(ImsInvoiceItem::getApplyname,umsAdmin.getNickName())
                        .set(ImsInvoiceItem::getApplycdoe,umsAdmin.getUsername())
                        //.set(ImsInvoiceItem::getApplyje,0)
                );
                //invoiceItemService.updateStatusApply(invoiceItem.getId(),umsAdmin.getNickName(),umsAdmin.getUsername(),-1,0,InvoiceStatusEnums.NOT.getCode(),-1);
            }
        }catch (Exception e){
            LOGGER.info("退回接口异常:   " + ExceptionUtil.getStackTrace(e));
            e.printStackTrace();
            return CommonResult.failed("退回失败,请检查单据信息");
        }

        //添加主表回退记录
        List<ImsInvoice> invoices = new ArrayList<>();
        invoices.add(invoice);
        //returnInvoiceService.add(invoices);
        //添加子表回退记录
        //returnInvoiceItemService
        return CommonResult.success("退回成功");
    }

//    private boolean updateBatchInvoice(List<InvoiceDto> dtos) {
//        dtos.forEach(dto -> {
//            ImsInvoice ms = new ImsInvoice();
//            BeanUtil.copyProperties(dto, ms);
//
//            List<ImsInvoiceItem> collect = dto.getInvoiceItems().stream().peek(mms -> {
//                mms.setBillSerial(dto.getBillSerial());
//                mms.setStatus(InvoiceStatusEnums.SUCCESS.getCode());
//            }).collect(Collectors.toList());
//            invoiceItemService.updateBatchById(collect);
//
//            // 修改对应的单据明细状态后 查询此单明细是否都已开票 修改对应单据状态
//            List<ImsInvoiceItem> items = invoiceItemService.listByBillId(dto.getId());
//            List<ImsInvoiceItem> collect1 = items.stream().filter(item -> item.getStatus() == InvoiceStatusEnums.IN.getCode() || item.getStatus() == InvoiceStatusEnums.SUCCESS.getCode()).collect(Collectors.toList());
//
//            if (collect1.size() == items.size()) ms.setStatus(InvoiceStatusEnums.SUCCESS.getCode());
//            else ms.setStatus(InvoiceStatusEnums.HALF.getCode());
//            invoiceService.updateById(ms);
//        });
//        return true;
//    }

    @Override
    public CommonResult queryInvoiceApply(String fpqqlsh) {
        Map<String, String> paramsMap = new HashMap<>();
        paramsMap.put("fpqqlsh", fpqqlsh);
        OpenBillBuilder builder = new OpenBillBuilder();
        try {
            LOGGER.info("查询蓝票接口参数报文:   " + paramsMap);

            //Map resultMap = builder.callInvoiceApply(DOMAIN + QUERY_URL + APP_ID, paramsMap);
            Map resultMap = openBillBuilder.callInvoiceApply(DOMAIN + QUERY_URL + APP_ID, paramsMap);
            if ("1002".equals(resultMap.get("code"))) return CommonResult.failed("数据不存在");

            // 查询得到的data和回调服务相同


            return CommonResult.success(resultMap);
        } catch (Exception e) {
            LOGGER.info("查询接口异常:   " + ExceptionUtil.getStackTrace(e));
            e.printStackTrace();
            return CommonResult.failed("查询失败");
        }
    }

    @Autowired
    CacheService cacheService;
    @Override
    public Map<String, String> callbackInvoiceApply(CallbackInvoiceParam param) {
        Map<String, String> map = new HashMap<>();
        LOGGER.debug("税务云开蓝票回调结果" + param);
        QueryWrapper<ImsInvoice> imsInvoiceQueryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<ImsInvoice> invoiceLambdaQueryWrapper = imsInvoiceQueryWrapper.lambda();
        invoiceLambdaQueryWrapper.eq(ImsInvoice::getBillSerial, param.getFpqqlsh());
        ImsInvoice imsInvoice=invoiceService.getOne(invoiceLambdaQueryWrapper);
        //UmsAdmin umsAdmin=adminService.getAdminByUsername(imsInvoice.getApplycdoe());//获取用户
        Gson gson = new Gson();
        CallbackInvoiceData data = gson.fromJson(param.getData(), CallbackInvoiceData.class);
        if (BeanUtil.isEmpty(imsInvoice)) {

            if(data.getLyid()!=null&&!("".equals(data.getLyid()))){
                CallbackInvoiceParam callbackInvoiceParam=cacheService.getCahe().get(data.getLyid());
                param.setFpqqlsh(data.getLyid());
                String luid=data.getLyid();
                if (callbackInvoiceParam==null){
                    cacheService.getCahe().put(luid,param.clone());
                    try {
                        long a= cacheService.getCahe().getExpectedExpiration(luid);
                        LOGGER.debug("第一次剩余过期时间:" +a+"");
                    }catch (Exception e){
                        LOGGER.debug(luid+"已过期:" +0+"");
                    }
                    map.put("code","1000");
                    map.put("msg","回传成功");
                }else {
                    CallbackInvoiceData callbackInvoiceData = gson.fromJson(callbackInvoiceParam.getData(), CallbackInvoiceData.class);//缓存数据
                    BigDecimal Jshj= (new BigDecimal(callbackInvoiceData.getJshj()).add(new BigDecimal(data.getJshj()).setScale(2,BigDecimal.ROUND_HALF_UP))).setScale(2,BigDecimal.ROUND_HALF_UP);//价税合计
                    BigDecimal Hjse=(new BigDecimal(callbackInvoiceData.getHjse()).add(new BigDecimal(data.getHjse()).setScale(2,BigDecimal.ROUND_HALF_UP))).setScale(2,BigDecimal.ROUND_HALF_UP);//合计税额
                    BigDecimal Hjje=(new BigDecimal(callbackInvoiceData.getHjje()).add(new BigDecimal(data.getHjje()).setScale(2,BigDecimal.ROUND_HALF_UP))).setScale(2,BigDecimal.ROUND_HALF_UP);//合计金额
                    callbackInvoiceData.setJshj(Jshj.doubleValue());
                    callbackInvoiceData.setHjse(Hjse.doubleValue());
                    callbackInvoiceData.setHjje(Hjje.doubleValue());
                    callbackInvoiceData.setFpqqlsh(luid);
                    callbackInvoiceData.setLyid(null);
                    callbackInvoiceData.setFpHm(callbackInvoiceData.getFpHm()+"/"+data.getFpHm());
                    int length= callbackInvoiceData.getFpHm().length();
                    if(length>=40){
                        callbackInvoiceData.setFpHm(callbackInvoiceData.getFpHm().substring(0, 40));
                    }
                    String json= JSONObject.toJSONString(callbackInvoiceData);
                    callbackInvoiceParam.setData(json);
                    try {
                        long a= cacheService.getCahe().getExpectedExpiration(luid);
                        LOGGER.debug("剩余过期时间:" +a+"");
                    }catch (Exception e){
                        LOGGER.debug(luid+"已过期:" +0+"");
                    }

                }
                map.put("code","1000");
                map.put("msg","回传成功");
                //data.setFpDm();
            }else {
                map.put("code","1001");
                map.put("msg","根据流水号未查出发票信息");
            }

            return map;
        }


        if ("0000".equals(param.getCode())) {
            if("Y".equals(data.getZfbz())){
                return map;
            }
            Double fuje="1".equals(imsInvoice.getDef1())?data.getJshj():data.getHjje();
            Double kpje="1".equals(imsInvoice.getDef1())?imsInvoice.getPayAmount().setScale(2, RoundingMode.HALF_UP).doubleValue():imsInvoice.getWsje().setScale(2, RoundingMode.HALF_UP).doubleValue();
            Map<String, String> params= new HashMap<>();
            params.put("lx", imsInvoice.getDjlx());
            params.put("pk", imsInvoice.getDef10());
            params.put("fphm", data.getFpHm());
            params.put("fpdm",data.getFpDm());
            BigDecimal wcjshe =(imsInvoice.getPayAmount().subtract(new BigDecimal(data.getJshj()).setScale(2,BigDecimal.ROUND_HALF_UP))).setScale(2,BigDecimal.ROUND_HALF_UP);
            BigDecimal wchjse =(imsInvoice.getTaxAmount().subtract(new BigDecimal(data.getHjse()).setScale(2,BigDecimal.ROUND_HALF_UP))).setScale(2,BigDecimal.ROUND_HALF_UP);
            BigDecimal wcwsje =(imsInvoice.getWsje().subtract(new BigDecimal(data.getHjje()).setScale(2,BigDecimal.ROUND_HALF_UP))).setScale(2,BigDecimal.ROUND_HALF_UP);
            params.put("wcjshe",wcjshe+"");//价税合计
            params.put("wchjse",wchjse+"");//合计税额
            params.put("wcwsje",wcwsje+"");//合计金额
            params.put("kplx",imsInvoice.getDef1());
            params.put("userid", imsInvoice.getApplycdoe());
            if (wcjshe.doubleValue()>1||wcjshe.doubleValue()<-1){
                LOGGER.debug("价税合计尾插大于1：" + wcjshe);
                map.put("code","1001");
                map.put("msg","价税合计尾插大于1"+ wcjshe);
                return map;
            }
            if (wchjse.doubleValue()>1||wchjse.doubleValue()<-1){
                LOGGER.debug("合计税额尾插大于1：" + wchjse);
                map.put("code","1001");
                map.put("msg","合计税额尾插大于1" + wchjse);
                return map;
            }
            if (wcwsje.doubleValue()>1||wcwsje.doubleValue()<-1){
                LOGGER.debug("合计金额尾插大于1：" + wcwsje);
                map.put("code","1001");
                map.put("msg","合计金额尾插大于1");
                return map;
            }

            try {
                LOGGER.debug("NC发送信息：" + JSONUtils.toJSONString(params));
                String a=HttpRestUtils.post(NC_URL,JSONUtils.toJSONString(params));
                LOGGER.debug("NC返回：" + a);
            } catch (Exception e) {
                LOGGER.info("NC接口异常:   " + ExceptionUtil.getStackTrace(e));
                LOGGER.error( "NC发送失败"+e.getMessage());
            }

            LambdaUpdateWrapper<ImsInvoice> imsInvoiceLambdaUpdateWrapper=new LambdaUpdateWrapper<>();
            imsInvoiceLambdaUpdateWrapper.eq(ImsInvoice::getBillSerial, param.getFpqqlsh())
                    .set(ImsInvoice::getStatus, InvoiceStatusEnums.SUCCESS.getCode())
                    .set(ImsInvoice::getDef3, param.getShareurl()==null?"":param.getShareurl())//发票提URL
                    .set(ImsInvoice::getDef2, param.getSharecode()==null?"":param.getSharecode())//发票提取码
                    .set(ImsInvoice::getBillNo, data.getFpHm()==null?"":data.getFpHm())//
                    .set(ImsInvoice::getBillCode, data.getFpDm()==null?"":data.getFpDm());
            invoiceService.update(imsInvoiceLambdaUpdateWrapper);
            LambdaUpdateWrapper<ImsInvoiceItem> itemLambdaUpdateWrapper=new LambdaUpdateWrapper<>();
            itemLambdaUpdateWrapper.eq(ImsInvoiceItem::getBillSerial, param.getFpqqlsh())//**********发票流水唯一
                    .set(ImsInvoiceItem::getStatus, InvoiceStatusEnums.SUCCESS.getCode() );
            invoiceItemService.update(itemLambdaUpdateWrapper);
            //return "开票成功";
        } else {
            LambdaUpdateWrapper<ImsInvoice> imsInvoiceLambdaUpdateWrapper=new LambdaUpdateWrapper<>();
            imsInvoiceLambdaUpdateWrapper.eq(ImsInvoice::getBillSerial, param.getFpqqlsh())
                    .set(ImsInvoice::getStatus, InvoiceStatusEnums.FAILED.getCode());
            invoiceService.update(imsInvoiceLambdaUpdateWrapper);
            LambdaUpdateWrapper<ImsInvoiceItem> itemLambdaUpdateWrapper=new LambdaUpdateWrapper<>();
            itemLambdaUpdateWrapper.eq(ImsInvoiceItem::getBillSerial, param.getFpqqlsh())
                    .set(ImsInvoiceItem::getStatus, InvoiceStatusEnums.FAILED.getCode() );
            invoiceItemService.update(itemLambdaUpdateWrapper);
            //return "开票失败";
            map.put("code", "1001");
            map.put("msg", param.getMsg());
            LOGGER.debug("回调返回：" + param);
            return map;
        }
        map.put("code", "0000");
        map.put("msg", "开票成功");
        LOGGER.debug("回调返回：" + param);
        return map;
    }

    @Override
    public Map<String, String> callredInvoiceApply(CallbackInvoiceParam param) {
        Map<String, String> map = new HashMap<>();
        LOGGER.debug("税务云开红票回调结果" + param);
        String code="0000";
        map.put("code", "0000");

        QueryWrapper<ImsInvoice> imsInvoiceQueryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<ImsInvoice> invoiceLambdaQueryWrapper = imsInvoiceQueryWrapper.lambda();
        invoiceLambdaQueryWrapper.eq(ImsInvoice::getBillSerial, param.getFpqqlsh());
        ImsInvoice imsInvoice=invoiceService.getOne(invoiceLambdaQueryWrapper);


        if (BeanUtil.isEmpty(imsInvoice)) {
            map.put("msg","根据流水号未查出发票信息");
            return map;
        }

        Gson gson = new Gson();
        CallbackInvoiceData data = gson.fromJson(param.getData(), CallbackInvoiceData.class);

        if ("0000".equals(param.getCode())) {
            if("Y".equals(data.getZfbz())){
                return map;
            }
            LambdaUpdateWrapper<ImsInvoice> imsInvoiceLambdaUpdateWrapper=new LambdaUpdateWrapper<>();
            Map<String, String> params= new HashMap<>();
            params.put("lx", imsInvoice.getDjlx());
            params.put("pk", imsInvoice.getDef10());
            params.put("fphm", data.getFpHm());
            params.put("fpdm",data.getFpDm());
            params.put("userid", imsInvoice.getApplycdoe());
            try {
                LOGGER.debug("NC发送信息：" + JSONUtils.toJSONString(params));
                String a=HttpRestUtils.post(NC_URL,JSONUtils.toJSONString(params));
                LOGGER.debug("NC返回：" + a);
            } catch (Exception e) {
                LOGGER.info("NC接口异常:   " + ExceptionUtil.getStackTrace(e));
                LOGGER.error( "NC发送失败"+e.getMessage());
            }

            imsInvoiceLambdaUpdateWrapper.eq(ImsInvoice::getBillSerial, param.getFpqqlsh())
                    .set(ImsInvoice::getStatus, InvoiceStatusEnums.RED.getCode())
                    .set(ImsInvoice::getDef3, param.getShareurl()==null?"":param.getShareurl())//发票提URL
                    .set(ImsInvoice::getDef2, param.getSharecode()==null?"":param.getSharecode())//发票提取码
                    .set(ImsInvoice::getRedBillNo, data.getFpHm()==null?"":data.getFpHm())//
                    .set(ImsInvoice::getRedBillCode, data.getFpDm()==null?"":data.getFpDm());
            invoiceService.update(null,imsInvoiceLambdaUpdateWrapper);
            LambdaUpdateWrapper<ImsInvoiceItem> itemLambdaUpdateWrapper=new LambdaUpdateWrapper<>();
            itemLambdaUpdateWrapper.eq(ImsInvoiceItem::getBillSerial, param.getFpqqlsh())
                    .set(ImsInvoiceItem::getStatus, InvoiceStatusEnums.RED.getCode() );
            invoiceItemService.update(null,itemLambdaUpdateWrapper);
            map.put("msg", "开票成功");
            LOGGER.debug("回调返回：" + param);
            return map;
        }else {
            LambdaUpdateWrapper<ImsInvoice> imsInvoiceLambdaUpdateWrapper=new LambdaUpdateWrapper<>();
            imsInvoiceLambdaUpdateWrapper.eq(ImsInvoice::getBillSerial, param.getFpqqlsh())
                    .set(ImsInvoice::getStatus, InvoiceStatusEnums.FAILED.getCode());
            invoiceService.update(null,imsInvoiceLambdaUpdateWrapper);
            LambdaUpdateWrapper<ImsInvoiceItem> itemLambdaUpdateWrapper=new LambdaUpdateWrapper<>();
            itemLambdaUpdateWrapper.eq(ImsInvoiceItem::getBillSerial, param.getFpqqlsh())
                    .set(ImsInvoiceItem::getStatus, InvoiceStatusEnums.FAILED.getCode() );
            invoiceItemService.update(null,itemLambdaUpdateWrapper);
            //return "开票失败";
            map.put("code", "1001");
            map.put("msg", param.getMsg());
            LOGGER.debug("回调返回：" + param);
            return map;
        }

    }


    @Override
    public Map<String, String> openRedBillCallback(CallbackInvoiceParam callbackInvoiceParam) {
        return callredInvoiceApply(callbackInvoiceParam);
    }

    /**
     * 开红票
     * @param ids 发票id
     * @return
     */
    @Override
    public CommonResult openRedInvoice(Principal principal,List<String> ids) {
        if (ids==null) return CommonResult.failed("请选择发票开红票");
        //查出待开票和部分开票的主表
        List<ImsInvoice> imsInvoices = invoiceService.list(new LambdaQueryWrapper<ImsInvoice>()
                .in(ImsInvoice::getStatus, InvoiceStatusEnums.APPLY.getCode(), InvoiceStatusEnums.HALF.getCode())
                .in(ImsInvoice::getId, ids)
        );
        UmsAdmin umsAdmin = adminService.getAdminByUsername(principal.getName());
        try {
            return openRedapply(imsInvoices,umsAdmin);
        }catch (Exception e){
            LOGGER.info("开红票接口异常:   " + ExceptionUtil.getStackTrace(e));
            e.printStackTrace();
            return CommonResult.failed("开红票失败,请检查单据信息");
        }

    }

    private CommonResult openRedapply(List<ImsInvoice> es,UmsAdmin umsAdmin){


        List<ImsInvoice> bills =es;
//        long n0 = bills.stream().filter(b -> b.getBillType() == 4).count();
//        if (n0 > 0) return CommonResult.failed("增值税专用发票需手动红冲");

 //       if (bills.size() > 10) return CommonResult.failed("每次开票不能超过10");
  //      long num = bills.stream().filter(b -> b.getStatus() != InvoiceStatusEnums.SUCCESS.getCode()).count();
//        if (num > 0) return CommonResult.failed("发票未成功开票,不能红冲!");
//
//        long n1 = bills.stream().filter(b -> DateUtil.isSameMonth(DateUtil.parse(b.getCreateTime()), DateUtil.date())).count();
//        if (n1 > 0) return CommonResult.failed("当月发票不能红冲!");

        List<Object> dtos = new ArrayList<>();
        List<Object> urls = new ArrayList<>();
        List<Object> emails = new ArrayList<>();
        List<Object> phones = new ArrayList<>();

        bills.forEach(bill -> {
            String[] a= bill.getBlueBillNo().split("/");

            for (int i = 0; i < a.length; i++) {
                Map<String, Object> dto = new HashMap<>();
                String serial = OpenBillBuilder.createSerialNumber();
                bill.setBillSerial(serial);
                if (i==0){
                    bill.setDef7(serial);//记入流水号
                }else {
                    bill.setDef7(serial+"/"+bill.getDef7());
                }
                dto.put("FPQQLSH", serial);
                dto.put("fpDm", bill.getBlueBillCode());
                dto.put("fpHm", bill.getBlueBillNo());
                dto.put("hzxxbbh",bill.getRedapplycode());
                dto.put("userid", bill.getApplycdoe());
                dto.put("HCYY",1);
//            dto.put("ALLELCPASSWORD",null);
                dtos.add(dto);
                Map<String, Object> url = new HashMap<>();
                url.put("fpqqlsh", serial);
                url.put("url", CALLBACK_RED_URL);
                urls.add(url);
            }
//            Map<String, Object> phone = new HashMap<>();
//            phone.put("fpqqlsh", serial);
//            phone.put("address", CALLBACK_PHONE);
//            phones.add(phone);
//
//            Map<String, Object> email = new HashMap<>();
//            email.put("fpqqlsh", serial);
//            email.put("address", CALLBACK_EMAIL);
//            emails.add(email);


        });


        GsonBuilder builder = new GsonBuilder();

        Map<String, String> paramsMap = new HashMap<>();
        paramsMap.put("requestdatas", builder.create().toJson(dtos));
        paramsMap.put("email", builder.create().toJson(emails));
        paramsMap.put("sms", builder.create().toJson(phones));
        paramsMap.put("url", builder.create().toJson(urls));
        paramsMap.put("autoAudit", "false");

        LOGGER.info("普票红冲接口参数报文:   " + paramsMap);

        Map<String, String> resultMap = openBillBuilder.callInvoiceApply(DOMAIN + RED_URL + APP_ID, paramsMap);
        LOGGER.info("普票红冲接口返回报文:   " + resultMap);
        try {
            if ("0000".equals(resultMap.get("code"))) {

                for(ImsInvoice invoice:es) {
                    LambdaUpdateWrapper<ImsInvoice> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                    lambdaUpdateWrapper.eq(ImsInvoice::getId, invoice.getId())
                            .set(ImsInvoice::getStatus, InvoiceStatusEnums.IN.getCode())
                            .set(ImsInvoice::getApplyname,umsAdmin.getNickName())
                            .set(ImsInvoice::getApplycdoe,umsAdmin.getUsername())
                            .set(ImsInvoice::getBillSerial, invoice.getBillSerial());
                    invoiceService.update(lambdaUpdateWrapper);
                    List<ImsInvoiceItem> items = invoiceItemService.list(new LambdaQueryWrapper<ImsInvoiceItem>()
                            .eq(ImsInvoiceItem::getManualId, invoice.getId())
                            .eq(ImsInvoiceItem::getStatus,InvoiceStatusEnums.APPLY.getCode())
                    );
                    // invoiceService.updateStatusApply(invoice.getBillSn(), umsAdmin.getNickName(), umsAdmin.getUsername(), invoice.getBillType(), 0, InvoiceStatusEnums.IN.getCode());
                    for (ImsInvoiceItem invoiceItem : items) {
                        LambdaUpdateWrapper<ImsInvoiceItem> lambdaUpdateWrapperb = new LambdaUpdateWrapper<>();
                        lambdaUpdateWrapperb.eq(ImsInvoiceItem::getId, invoiceItem.getId())
                                .set(ImsInvoiceItem::getStatus, InvoiceStatusEnums.IN.getCode())
                                .set(ImsInvoiceItem::getBillSerial, invoice.getBillSerial());
                        invoiceItemService.update(lambdaUpdateWrapperb);
                        //invoiceItemService.updateStatusApply(invoiceItem.getId(), umsAdmin.getNickName(), umsAdmin.getUsername(), -1, 0, InvoiceStatusEnums.IN.getCode());
                    }
                }
                return CommonResult.success(resultMap.get("msg"));
            } else {
                return CommonResult.failed(resultMap.get("msg"));
            }
        } catch (Exception e) {
            LOGGER.info("开红票接口异常:" + ExceptionUtil.getStackTrace(e));
            e.printStackTrace();
            return CommonResult.failed("开票失败");
        }
    }

    /**
     * 开蓝票
     * @param ids 发票id
     * @return
     */
    @Override
    public CommonResult openBlueInvoice(Principal principal,List<String> ids) {
        if (ids==null) return CommonResult.failed("请选择发票开蓝票");

        if (ids.size() > 10) return CommonResult.failed("每次开票不能超过10");
        //查出待开票和部分开票的主表
        List<ImsInvoice> imsInvoices = invoiceService.list(new LambdaQueryWrapper<ImsInvoice>()
                //.in(ImsInvoice::getStatus, InvoiceStatusEnums.APPLY.getCode(), InvoiceStatusEnums.HALF.getCode())
                .in(ImsInvoice::getId, ids)
        );
        UmsAdmin umsAdmin = adminService.getAdminByUsername(principal.getName());
        //根据主表id查询关联的子表
        try {
            return apply(imsInvoices,umsAdmin);
        }catch (Exception e){
            LOGGER.info("开蓝票接口异常:   " + ExceptionUtil.getStackTrace(e));
            e.printStackTrace();
            return CommonResult.failed("开蓝票失败,请检查单据信息");
        }

    }

    @Override
    public String as() {
        LOGGER.info("回单监听关闭，开始处理监听数据-------");
        return "";
    }


    private CommonResult apply(List<ImsInvoice> es,UmsAdmin umsAdmin){
            List<ImsInvoiceItem> additems=new ArrayList<>();
            GsonBuilder builder = new GsonBuilder();
            List<Object> datas = new ArrayList<>();
            List<Object> urls = new ArrayList<>();
            List<Object> emails = new ArrayList<>();
            List<Object> phones = new ArrayList<>();
            List<Object> delurl = new ArrayList<>();
            for (ImsInvoice e: es) {
                UmsNcOrg orgCustomer = null;
                UmsNcCustomer customer = null;
                if ("lp".equals(e.getDjlx())){
                    QueryWrapper<UmsNcCustomer> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("pk_nc", e.getPkNccust());
                    UmsNcCustomer one = umsNcCustomerService.getOne(queryWrapper);
                    if (one==null) return CommonResult.failed("根据单据信息未能查询到对应的客户，请检查客户信息或同步数据");
                    customer = one;
                }else {
                    QueryWrapper<UmsNcCustomer> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("pk_nc", e.getPkNccust());
                    UmsNcCustomer one = umsNcCustomerService.getOne(queryWrapper);
                    if (one==null) return CommonResult.failed("根据单据信息未能查询到对应的客户，请检查客户信息或同步数据");
                    customer = one;
                }

                UmsNcOrg org = orgService.getData(e.getSellerSn());
                if (org==null) return CommonResult.failed("根据单据信息未能查询到对应的组织，请检查组织信息或同步数据");
                String serial = OpenBillBuilder.createSerialNumber();//流水号
                e.setBillSerial(serial);
                Map<String, Object> data = new HashMap<>();
                data.put("FPQQLSH", serial);
                data.put("FPLX", e.getBillType());
                data.put("BZ", e.getNote());
                data.put("XSF_NSRSBH", org.getTaxpayerid());//纳税人识别号
                data.put("XSF_MC", e.getPartyName());//名字
                //data.put("HJJE", e.getWsje());//合计金额
                String corpaddresa=org.getCorpaddres()==null?"":org.getCorpaddres();
                String tela= org.getTel()==null?"":org.getTel();
                String XSF_DZDH=corpaddresa+" "+tela;

                if (e.getBillType().equals(31)||e.getBillType().equals(32)){

                    data.put("XSF_DZ", corpaddresa);//地址
                    data.put("XSF_DH", tela);//电话
                    data.put("XSF_YHZH", org.getDef2());//银行账号
                    if (orgCustomer!=null){
                        data.put("GMF_NSRSBH", orgCustomer.getTaxpayerid());//购买方纳税人识别号
                        data.put("GMF_MC", e.getBuyerName());
                        String corpaddres=orgCustomer.getCorpaddres()==null?"":orgCustomer.getCorpaddres();
                        String tel= orgCustomer.getTel()==null?"":orgCustomer.getTel();
                        data.put("GMF_DZ", corpaddres);
                        data.put("GMF_DH",tel);
                        data.put("GMF_YH", orgCustomer.getBankdoc());
                        data.put("GMF_ZH", orgCustomer.getCustbank());
                        // data.put("ORGCODE", org.getCode());//组织编码
                        //data.put("KPR", umsAdmin.getNickName());
                    }else if (customer!=null){
                        data.put("GMF_NSRSBH", customer.getTaxpayerid());//购买方纳税人识别号
                        data.put("GMF_MC", customer.getName());
                        String corpaddres=customer.getCorpaddres()==null?"":customer.getCorpaddres();
                        String tel= customer.getTel()==null?"":customer.getTel();
                        data.put("GMF_DZ", corpaddres);
                        data.put("GMF_DH",tel);
                        data.put("GMF_YH", customer.getBankdoc());
                        data.put("GMF_ZH", customer.getCustbank());
                        //data.put("ORGCODE", org.getCode());//组织编码
                        //data.put("KPR", umsAdmin.getNickName());
                    }




                }else {
                    data.put("XSF_DZDH", (XSF_DZDH).substring(0, XSF_DZDH.length()>=100?100:XSF_DZDH.length()));//地址
                    data.put("XSF_YHZH", org.getDef2());//银行账号
                    if (orgCustomer!=null){
                        data.put("GMF_NSRSBH", orgCustomer.getTaxpayerid());//购买方纳税人识别号
                        data.put("GMF_MC", e.getBuyerName());
                        String corpaddres=orgCustomer.getCorpaddres()==null?"":orgCustomer.getCorpaddres();
                        String tel= orgCustomer.getTel()==null?"":orgCustomer.getTel();
                        String GMF_DZDH=corpaddres+" "+tel;
                        data.put("GMF_DZDH", (GMF_DZDH).substring(0, GMF_DZDH.length()>=100?100:GMF_DZDH.length()));
                        data.put("GMF_YHZH", orgCustomer.getDef2());
                        //data.put("ORGCODE", org.getCode());//组织编码
                        //data.put("KPR", umsAdmin.getNickName());

                    }else if (customer!=null){
                        data.put("GMF_NSRSBH", customer.getTaxpayerid());//购买方纳税人识别号
                        data.put("GMF_MC", customer.getName());
                        String corpaddres=customer.getCorpaddres()==null?"":customer.getCorpaddres();
                        String tel= customer.getTel()==null?"":customer.getTel();
                        String GMF_DZDH=corpaddres+" "+tel;

                        data.put("GMF_DZDH", (GMF_DZDH).substring(0, GMF_DZDH.length()>=100?100:GMF_DZDH.length()));
                        data.put("GMF_YHZH", customer.getDef2());
                        //data.put("ORGCODE", org.getCode());//组织编码
                        //data.put("KPR", umsAdmin.getNickName());


                    }
                }



                List<ImsInvoiceItem> items = invoiceItemService.list(new LambdaQueryWrapper<ImsInvoiceItem>()
                        .eq(ImsInvoiceItem::getManualId, e.getId())
                        .eq(ImsInvoiceItem::getStatus,InvoiceStatusEnums.APPLY.getCode())
                        .last(" ORDER BY CAST(DEF6 AS number)")
                );
                items.forEach(esa->{ esa.setBillSerial(serial);additems.add(esa);});
                BigDecimal reduce = BigDecimal.ZERO;
               // reduce = items.stream().map(ImsInvoiceItem::getApplyje).reduce(BigDecimal.ZERO, BigDecimal::add);
                reduce = items.stream().map(ImsInvoiceItem::getTaxAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                //data.put("JSHJ", reduce);

                data.put("items", openBillBuilder.buildItems(items, Integer.valueOf(e.getDef1()) ));
                datas.add(data);

                Map<String, Object> url = new HashMap<>();
                url.put("fpqqlsh", serial);
                url.put("url", CALLBACK_URL);
                urls.add(url);

                Map<String, Object> del = new HashMap<>();
                del.put("fpqqlsh", serial);
                del.put("url", RETURN_URL);
                delurl.add(del);

                if (orgCustomer!=null){
//                    Map<String, Object> phone = new HashMap<>();
//                    phone.put("fpqqlsh", serial);
//                    phone.put("address", orgCustomer.getTel()==null?"":orgCustomer.getTel());
//                    phone.put("title", "电子发票 : " + serial);
//                    phone.put("content", e.getBillContent());
//                    phones.add(phone);

                    Map<String, Object> email = new HashMap<>();
                    email.put("fpqqlsh", serial);
                    email.put("address", orgCustomer.getDef1()==null?"":orgCustomer.getDef1());
                    emails.add(email);
                }else if (customer!=null){
//                    Map<String, Object> phone = new HashMap<>();
//                    phone.put("fpqqlsh", serial);
//                    phone.put("address",  customer.getTel()==null?"":customer.getTel());
//                    phone.put("title", "电子发票 : " + serial);
//                    phone.put("content", e.getBillContent());
//                    phones.add(phone);

                    Map<String, Object> email = new HashMap<>();
                    email.put("fpqqlsh", serial);
                    email.put("address", customer.getDef1()==null?"":customer.getDef1());
                    emails.add(email);
                }
            }
            Map<String, String> paramsMap = new HashMap<>();
            paramsMap.put("requestdatas", builder.create().toJson(datas));
            paramsMap.put("email", builder.create().toJson(emails));
           // paramsMap.put("sms", builder.create().toJson(phones));
            paramsMap.put("url", builder.create().toJson(urls));
            paramsMap.put("autoAudit", "false");
            paramsMap.put("delurl", builder.create().toJson(delurl));
            LOGGER.info("开蓝票接口参数报文:   " + paramsMap);

            Map resultMap = openBillBuilder.callInvoiceApply(DOMAIN + SPLIT_URL + APP_ID, paramsMap);

            LOGGER.info("开蓝票接口返回报文:   " + resultMap);

            if ("0000".equals(resultMap.get("code"))) {
                for(ImsInvoice invoice:es) {
                   // billService.splitAddOpenBill(invoice.getBillSn(), (List<Map<String, Object>>) resultMap.get("datas"));//新增发票信息
                    LambdaUpdateWrapper<ImsInvoice> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                    lambdaUpdateWrapper.eq(ImsInvoice::getId, invoice.getId())
                            .set(ImsInvoice::getStatus, InvoiceStatusEnums.IN.getCode())
                            .set(ImsInvoice::getCreateTime, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
                            .set(ImsInvoice::getBillSerial, invoice.getBillSerial());
                    invoiceService.update(lambdaUpdateWrapper);


                    List<ImsInvoiceItem> items = invoiceItemService.list(new LambdaQueryWrapper<ImsInvoiceItem>()
                            .eq(ImsInvoiceItem::getManualId, invoice.getId())
                            .eq(ImsInvoiceItem::getStatus,InvoiceStatusEnums.APPLY.getCode())
                    );
                   //invoiceService.updateStatusApply(invoice.getId() , umsAdmin.getNickName(), umsAdmin.getUsername(), invoice.getBillType(), invoice.getApplyje().longValue(), InvoiceStatusEnums.IN.getCode(),-1);
                   invoiceService.update(new LambdaUpdateWrapper<ImsInvoice>()
                           .eq(ImsInvoice::getId,invoice.getId())
                           .set(ImsInvoice::getStatus,InvoiceStatusEnums.IN.getCode())
                           .set(ImsInvoice::getApplyname,umsAdmin.getNickName())
                           .set(ImsInvoice::getApplycdoe,umsAdmin.getUsername())
                           .set(ImsInvoice::getBillType,invoice.getBillType())
                           //.set(ImsInvoice::getApplyje,invoice.getApplyje().doubleValue())
                   );
                    for (ImsInvoiceItem invoiceItem : items) {
                        LambdaUpdateWrapper<ImsInvoiceItem> lambdaUpdateWrapperb = new LambdaUpdateWrapper<>();
                        lambdaUpdateWrapperb.eq(ImsInvoiceItem::getId, invoiceItem.getId())
                                .set(ImsInvoiceItem::getStatus, InvoiceStatusEnums.IN.getCode())
                                .set(ImsInvoiceItem::getCreateTime, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
                                .set(ImsInvoiceItem::getBillSerial, invoice.getBillSerial());
                        invoiceItemService.update(lambdaUpdateWrapperb);
                       //invoiceItemService.updateStatusApply(invoiceItem.getId(), umsAdmin.getNickName(), umsAdmin.getUsername(), -1, 0, InvoiceStatusEnums.IN.getCode());
                    }
                }

            }else {
                return CommonResult.failed((String) resultMap.get("msg"));
            }

        return CommonResult.success("开蓝票成功");
    }

    @Override
    public Map<String, String> openReturn(OpenReturn openReturn) {
        QueryWrapper<ImsInvoice> imsInvoiceQueryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<ImsInvoice> invoiceLambdaQueryWrapper = imsInvoiceQueryWrapper.lambda();
        invoiceLambdaQueryWrapper.eq(ImsInvoice::getBillSerial, openReturn.getFpqqlsh());
        ImsInvoice imsInvoice=invoiceService.getOne(invoiceLambdaQueryWrapper);
        LOGGER.info("退回报文:   " + openReturn);
        if (imsInvoice == null){
            LOGGER.info("退回无法查到数据开票中的数据");
            return null;
        }
        LambdaUpdateWrapper<ImsInvoice> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(ImsInvoice::getBillSerial, openReturn.getFpqqlsh())
                .set(ImsInvoice::getStatus, InvoiceStatusEnums.FAILED.getCode());

        List<ImsInvoiceItem> items = invoiceItemService.list(new LambdaQueryWrapper<ImsInvoiceItem>()
                .eq(ImsInvoiceItem::getPkNch, imsInvoice.getPkNch())
                .in(ImsInvoiceItem::getStatus,InvoiceStatusEnums.IN.getCode())
        );

        for (ImsInvoiceItem invoiceItem : items) {
            LambdaUpdateWrapper<ImsInvoiceItem> lambdaUpdateWrapperb = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapperb.eq(ImsInvoiceItem::getId, invoiceItem.getId())
                    .set(ImsInvoiceItem::getStatus, InvoiceStatusEnums.FAILED.getCode());
            invoiceItemService.update(lambdaUpdateWrapperb);
            //invoiceItemService.updateStatusApply(invoiceItem.getId(), umsAdmin.getNickName(), umsAdmin.getUsername(), -1, 0, InvoiceStatusEnums.IN.getCode());
        }
        invoiceService.update(lambdaUpdateWrapper);
        Map<String,String> map=new HashMap<>();
        map.put("code", "0");
        return map;
    }

}
